package svc.elib.socnet;

import java.util.LinkedList;

import svc.elib.db.Author;
import svc.elib.db.Paper;

/**
 * Link in digital library network
 * 
 * @author svc
 * @date 7.6.2013
 */
public class Link {

	private Author src;
	private Author dst;
	private LinkedList<Paper> papersInCommon;

	/**
	 * year when the first paper of src and dst is published
	 */
	private int firstYear;
	
	
	/**
	 * year when the last paper of src and dst is published
	 */
	private int lastYear;
	private int collaborationSpan;
	
	
	public Link(Author src, Author dst) {
		this.src = src;
		this.dst = dst;
		
		papersInCommon = new LinkedList<Paper>();
		resolvePapersInCommon();
		determineCollaborationSpan();
	}
	
	public Link(Author src, Author dst, LinkedList<Paper> papersInCommon) {
		this.src = src;
		this.dst = dst;
		this.papersInCommon = papersInCommon;
		determineCollaborationSpan();
	}

	private void determineCollaborationSpan() {
		Paper start = papersInCommon.get(0);
		firstYear = start.getYear();
		lastYear = start.getYear();
		
		for (int i = 0; i < papersInCommon.size(); i++) {
			Paper p = papersInCommon.get(i);
			if (p.getYear() < firstYear)
				firstYear = p.getYear();
			if (p.getYear() > lastYear)
				lastYear = p.getYear();
		}
		
		collaborationSpan = lastYear - firstYear + 1;
	}
	
	private void resolvePapersInCommon() {
		
		LinkedList<Paper> pic1 = new LinkedList<Paper>();
		LinkedList<Paper> pic2 = new LinkedList<Paper>();
		
		LinkedList<Paper> srcPapers = src.getPapers();
		for (int i = 0; i < srcPapers.size(); i++) {
			Paper p = srcPapers.get(i);
			if (p.isAuthor(dst)) {
				pic1.addLast(p);
			}
		}
		
		LinkedList<Paper> dstPapers = dst.getPapers();
		for (int i = 0; i < dstPapers.size(); i++) {
			Paper p = dstPapers.get(i);
			if (p.isAuthor(src)) {
				pic2.addLast(p);
			}
		}
		
		boolean ok = check(pic1, pic2);
		if (!ok) {
			System.out.println("PapersInCommon error");
			src.printFullInfo();
			dst.printFullInfo();
		}
		
		papersInCommon = pic1;
	}
	
	private boolean check(LinkedList<Paper> l1, LinkedList<Paper> l2) {		
		for (int i = 0; i < l1.size(); i++) {
			Paper p = l1.get(i);
			if (!l2.contains(p)) {
				return false;
			}
		}
		
		for (int i = 0; i < l2.size(); i++) {
			Paper p = l2.get(i);
			if (!l1.contains(p)) {
				return false;
			}
		}
		
		return true;
	}
	
	public Author getSrc() { 
		return src; 
	}
	
	public Author getDst() { 
		return dst; 
	}

	public LinkedList<Paper> getPapersInCommon() {
		return papersInCommon;
	}

	public int getFirstYear() {
		return firstYear;
	}

	public int getLastYear() {
		return lastYear;
	}

	public int getCollaborationSpan() {
		return collaborationSpan;
	}
	
	public int getWeight() {
		return papersInCommon.size();
	}

	public String getName() {
		return src.getName() + "#" + dst.getName(); 
	}
}
